home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / cug236 / cb.c < prev    next >
Text File  |  1980-01-02  |  8KB  |  308 lines

  1. /*
  2.     HEADER:        CUG000.00;
  3.     TITLE:        C Source Formatter;
  4.     DATE:        04/04/1987;
  5.     DESCRIPTION:    "Formats a C source program with proper indents for
  6.             each statement.";
  7.     VERSION:    2.1;
  8.     KEYWORDS:    Pretty Printer;
  9.     FILENAME:    CB.C;
  10.     SEE-ALSO:    CB.DOC;
  11.     COMPILERS:    vanilla;
  12.     AUTHORS:    W. C. Colley III, J. W. Kindschi Jr.;
  13. */
  14.  
  15. /*
  16.     Modified for Portable C
  17.     by: William C. Colley, III (4 APR 1987)
  18.  
  19.     Modified for Lattice C Ver 1.01
  20.     by: John W. Kindschi Jr. (10-30-83)
  21.  
  22.     Swiped from CPIG'S UNIX system and modified to
  23.     run under BDS C by William C. Colley, III
  24.  
  25.  
  26. To use the program type the following command line:
  27.  
  28.     A>cb input.fil [output.fil]
  29.  
  30.     Where input.fil is the file to be pretty printed and [output.fil]
  31.     is the destination file. If no output file is specified, then
  32.     the output goes to standard output.
  33. */
  34.  
  35. #include <stdio.h>
  36.  
  37. /*
  38.  * Portability Note:  The AZTEC C compilers handle the binary/text file
  39.  * dichotomy differently from most other compilers.  Uncomment the following
  40.  * pair of #defines if you are running AZTEC C:
  41.  */
  42.  
  43. /*
  44. #define getc(f)        agetc(f)
  45. #define putc(c,f)    aputc(c,f)
  46. */
  47.  
  48. char cc, lchar, pchar, string[200];
  49. char *wif[] =    {   "if",   NULL        };
  50. char *welse[] = {   "else", NULL        };
  51. char *wfor[] =    {   "for",  NULL        };
  52. char *wds[] =    {   "case", "default",    NULL    };
  53.  
  54. int clevel, ct, iflev, ind[10], level, paren, sifflg[10], siflev[10];
  55. int sind[20][10], slevel[10], spflg[20][10], stabs[20][10];
  56. int aflg, bflg, eflg, ifflg = -1, pflg[10], qflg, sflg = 1;
  57. int c, j, lastchar, peek = -1, tabs;
  58. FILE *f1, *f2 = stdout;
  59.  
  60. void comment(), gotelse(), ptabs(), put_str();
  61.  
  62. int main(argc,argv)
  63. int argc;
  64. char *argv[];
  65. {
  66.     int getchr(), get_nl(), get_str(), lookup();
  67.  
  68.     /* Initialize everything here */
  69.  
  70.     if (argc < 2 || argc > 3) {
  71.     fprintf(stderr,"Usage:  CB input.fil { output.fil }\n");  return !0;
  72.     }
  73.     if (!(f1 = fopen(*++argv,"r"))) {
  74.     fprintf(stderr,"ERROR:  Cannot find file %s\n",*argv);  return !0;
  75.     }
  76.     if (argc == 3 && !(f2 = fopen(*++argv,"w"))) {
  77.     fprintf(stderr,"ERROR:  Cannot create file %s\n",*argv);  return !0;
  78.     }
  79.  
  80.     /* End of Initialization */
  81.  
  82.     while ((c = getchr()) != EOF) {
  83.     switch (c) {
  84.         default:    string[j++] = c;
  85.             if (c != ',') lchar = c;
  86.             break;
  87.  
  88.         case ' ':
  89.         case '\t':    if (lookup(welse) == 1) {
  90.                 gotelse();
  91.                 if (sflg == 0 || j > 0) string[j++] = c;
  92.                 put_str();    sflg = 0;  break;
  93.             }
  94.             if (sflg == 0 || j > 0) string[j++] = c;
  95.             break;
  96.  
  97.         case '\n':    if (eflg = lookup(welse) == 1) gotelse();
  98.             put_str();  fprintf(f2,"\n");  sflg = 1;
  99.             if (eflg == 1) {  pflg[level]++;  tabs++; }
  100.             else if(pchar == lchar) aflg = 1;
  101.             break;
  102.  
  103.         case '{':    if (lookup(welse) == 1) gotelse();
  104.             siflev[clevel] = iflev;     sifflg[clevel] = ifflg;
  105.             iflev = ifflg = 0;  clevel++;
  106.             if (sflg == 1 && pflg[level] != 0) {
  107.                 pflg[level]--;  tabs--;
  108.             }
  109.             string[j++] = c;  put_str();  get_nl();     put_str();
  110.             fprintf(f2,"\n");  tabs++;  sflg = 1;
  111.             if (pflg[level] > 0) {
  112.                 ind[level] = 1;  level++;  slevel[level] = clevel;
  113.             }
  114.             break;
  115.  
  116.         case '}':    clevel--;
  117.             if ((iflev = siflev[clevel]-1) < 0) iflev = 0;
  118.             ifflg = sifflg[clevel];     put_str();  tabs--;  ptabs();
  119.             if ((peek = getchr()) == ';') {
  120.                 fprintf(f2,"%c;",c);  peek = -1;
  121.             }
  122.             else fprintf(f2,"%c",c);
  123.             get_nl();  put_str();  fprintf(f2,"\n");  sflg = 1;
  124.             if (clevel < slevel[level] && level > 0) level--;
  125.             if (ind[level] != 0) {
  126.                 tabs -= pflg[level];  pflg[level] = ind[level] = 0;
  127.             }
  128.             break;
  129.  
  130.         case '"':
  131.         case '\'':    string[j++] = c;
  132.             while ((cc = getchr()) != c) {
  133.                 string[j++] = cc;
  134.                 if (cc == '\\') string[j++] = getchr();
  135.                 if (cc == '\n') { put_str();  sflg = 1; }
  136.             }
  137.             string[j++] = cc;
  138.             if (get_nl() == 1) { lchar = cc;  peek = '\n'; }
  139.             break;
  140.  
  141.         case ';':    string[j++] = c;  put_str();
  142.             if (pflg[level] > 0 && ind[level] == 0) {
  143.                 tabs -= pflg[level];  pflg[level] = 0;
  144.             }
  145.             get_nl();  put_str();  fprintf(f2,"\n");  sflg = 1;
  146.             if(iflev > 0 && ifflg == 1){ iflev--;  ifflg = 0; }
  147.             else iflev = 0;
  148.             break;
  149.  
  150.         case '\\':    string[j++] = c;  string[j++] = getchr();  break;
  151.  
  152.         case '?':    qflg = 1;  string[j++] = c;  break;
  153.  
  154.         case ':':    string[j++] = c;
  155.             if (qflg == 1) { qflg = 0;  break; }
  156.             if (!lookup(wds)) { sflg = 0;  put_str(); }
  157.             else { tabs--;    put_str();  tabs++; }
  158.             if ((peek = getchr()) == ';') {
  159.                 fprintf(f2,";");  peek = -1;
  160.             }
  161.             get_nl();  put_str();  fprintf(f2,"\n");  sflg = 1;
  162.             break;
  163.  
  164.         case '/':    string[j++] = c;
  165.             if ((peek = getchr()) != '*') break;
  166.             string[j++] = peek;  peek = -1;     comment();  break;
  167.  
  168.         case ')':    paren--;  string[j++] = c;  put_str();
  169.             if (get_nl() == 1) {
  170.                 peek = '\n';
  171.                 if (paren != 0) aflg = 1;
  172.                 else if (tabs > 0) {
  173.                 pflg[level]++;    tabs++;     ind[level] = 0;
  174.                 }
  175.             }
  176.             break;
  177.  
  178.         case '#':    string[j++] = c;
  179.             while ((cc = getchr()) != '\n') string[j++] = cc;
  180.             string[j++] = cc;  sflg = 0;  put_str();  sflg = 1;
  181.             break;
  182.  
  183.         case '(':    string[j++] = c;  paren++;
  184.             if (lookup(wfor) == 1) {
  185.                 while ((c = get_str()) != ';');
  186.                 ct = 0;
  187. cont:                while ((c = get_str()) != ')')
  188.                 if(c == '(') ct++;
  189.                 if (ct != 0) { ct--;  goto cont; }
  190.                 paren--;  put_str();
  191.                 if (get_nl() == 1) {
  192.                 peek = '\n';  pflg[level]++;
  193.                 tabs++;     ind[level] = 0;
  194.                 }
  195.                 break;
  196.             }
  197.             if (lookup(wif) == 1) {
  198.                 put_str();
  199.                 stabs[clevel][iflev] = tabs;
  200.                 spflg[clevel][iflev] = pflg[level];
  201.                 sind[clevel][iflev] = ind[level];
  202.                 iflev++;  ifflg = 1;
  203.             }
  204.     }
  205.     }
  206.     if (f2 != stdout && (ferror(f2) || fclose(f2))) {
  207.     fprintf(stderr,"ERROR:  Disk full\n");    return !0;
  208.     }
  209.     fclose(f1);     return 0;
  210. }
  211.  
  212. void ptabs()
  213. {
  214.     int i;
  215.  
  216.     for (i=0; i < tabs; i++) fprintf(f2,"\t");
  217. }
  218.  
  219. int getchr()
  220. {
  221.     if (peek < 0 && lastchar != ' ' && lastchar != '\t') pchar = lastchar;
  222.     lastchar = (peek < 0) ? getc(f1) : peek;  peek = -1;
  223.     return lastchar;
  224. }
  225.  
  226. void put_str()
  227. {
  228.     if (j > 0) {
  229.     if (sflg != 0) {
  230.         ptabs();  sflg = 0;
  231.         if (aflg == 1) {
  232.         aflg = 0;
  233.         if (tabs > 0) fprintf(f2,"    ");
  234.         }
  235.     }
  236.     string[j] = '\0';  fprintf(f2,"%s",string);  j = 0;
  237.     }
  238.     else if (sflg != 0) { sflg = 0;  aflg = 0; }
  239. }
  240.  
  241. int lookup(tab)
  242. char *tab[];
  243. {
  244.     char r;
  245.     int i,kk,k,l;
  246.  
  247.     if (j < 1) return 0;
  248.     for (kk = 0; string[kk] == ' '; ++kk);
  249.     for (i = 0; tab[i] != 0; i++) {
  250.     l = 0;
  251.     for (k=kk; (r = tab[i][l++]) == string[k] && r != '\0'; ++k);
  252.     if (r == '\0' && (string[k] < 'a' || string[k] > 'z')) return 1;
  253.     }
  254.     return 0;
  255. }
  256.  
  257. int get_str()
  258. {
  259.     char ch;
  260.  
  261. beg:
  262.     if ((ch = string[j++] = getchr()) == '\\') {
  263.     string[j++] = getchr();     goto beg;
  264.     }
  265.     if (ch == '\'' || ch == '"') {
  266.     while ((cc = string[j++] = getchr()) != ch)
  267.         if (cc == '\\') string[j++] = getchr();
  268.     goto beg;
  269.     }
  270.     if (ch == '\n') { put_str();  aflg = 1;  goto beg; }
  271.     else return ch;
  272. }
  273.  
  274. void gotelse()
  275. {
  276.     tabs = stabs[clevel][iflev];  pflg[level] = spflg[clevel][iflev];
  277.     ind[level] = sind[clevel][iflev];  ifflg = 1;
  278. }
  279.  
  280. int get_nl()
  281. {
  282.     while ((peek = getchr()) == '\t' || peek == ' ') {
  283.     string[j++] = peek;  peek = -1;
  284.     }
  285.     if ((peek = getchr()) == '/') {
  286.     peek = -1;
  287.     if ((peek = getchr()) == '*') {
  288.         string[j++] = '/';    string[j++] = '*';
  289.         peek = -1;    comment();
  290.     }
  291.     else string[j++] = '/';
  292.     }
  293.     if ((peek = getchr()) == '\n') { peek = -1;     return 1; }
  294.     return 0;
  295. }
  296.  
  297. void comment()
  298. {
  299. rep:
  300.     while ((c = string[j++] = getchr()) != '*')
  301.     if (c == '\n') { put_str();  sflg = 1; }
  302. gotstar:
  303.     if ((c = string[j++] = getchr()) != '/') {
  304.     if (c == '*') goto gotstar;
  305.     goto rep;
  306.     }
  307. }
  308.